package generator;

import dal.Configuracion;
import dto.Tabla;
import java.io.File;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Vector;

/**
 *
 * @author Jose Carlos Gutierrez
 */
public abstract class Generador {

    protected Hashtable<String, String> columnas;
    protected String path;

    public Generador(String path) {
        this.path = path;
    }

    public abstract Hashtable<String, String> getColumnas();

    protected void generarConfiguracion() {
        Escritor escritor = new Escritor(path + File.separatorChar + "config.xml");
        Configuracion objConfig = Configuracion.getConfiguracion();
        escritor.escribir("<?xml version=\"1.0\" ?>");
        escritor.escribir("<app-config>");
        escritor.escribir("\t<db-config>");
        escritor.escribir("\t\t<db-engine>" + objConfig.getDbEngine() + "</db-engine>");
        escritor.escribir("\t\t<db-host>" + objConfig.getDbHost() + "</db-host>");
        escritor.escribir("\t\t<db-port>" + (objConfig.getDbPort() == null ? "" : objConfig.getDbPort()) + "</db-port>");
        escritor.escribir("\t\t<db-instance>" + objConfig.getDbInstace() + "</db-instance>");
        escritor.escribir("\t\t<db-name>" + objConfig.getDbName() + "</db-name>");
        escritor.escribir("\t\t<db-user>" + objConfig.getDbUser() + "</db-user>");
        escritor.escribir("\t\t<db-password>" + objConfig.getDbPassword() + "</db-password>");
        escritor.escribir("\t</db-config>");
        escritor.escribir("</app-config>");
        escritor.cerrar();
    }

    protected void generarDAL(){
        File parent = new File(path + File.separatorChar + "dal");
        if(!parent.exists())
            parent.mkdir();

        //Generacion de IConexion
        Vector<String> lineas = Escritor.leer(new File("").getAbsolutePath() +
                File.separatorChar + "resources" + File.separatorChar + "IConexion.txt");
        Iterator<String> iterador = lineas.iterator();
        Escritor obj = new Escritor(parent.getAbsolutePath() + File.separatorChar + "IConexion.java");
        while(iterador.hasNext()){
            obj.escribir(iterador.next());
        }
        obj.cerrar();

        //Generacion de Conexion
        lineas = Escritor.leer(new File("").getAbsolutePath() +
                File.separatorChar + "resources" + File.separatorChar + "Conexion.txt");
        iterador = lineas.iterator();
        obj = new Escritor(parent.getAbsolutePath() + File.separatorChar + "Conexion.java");
        while(iterador.hasNext()){
            obj.escribir(iterador.next());
        }
        obj.cerrar();

        //Generacion de Conexion
        lineas = Escritor.leer(new File("").getAbsolutePath() +
                File.separatorChar + "resources" + File.separatorChar + "Conexion" +
                Configuracion.getConfiguracion().getDbEngine() + ".txt");
        iterador = lineas.iterator();
        obj = new Escritor(parent.getAbsolutePath() + File.separatorChar + "Conexion" +
                Configuracion.getConfiguracion().getDbEngine() + ".java");
        while(iterador.hasNext()){
            obj.escribir(iterador.next());
        }
        obj.cerrar();

        //Generacion de IConexion
        lineas = Escritor.leer(new File("").getAbsolutePath() +
                File.separatorChar + "resources" + File.separatorChar + "Configuracion.txt");
        iterador = lineas.iterator();
        obj = new Escritor(parent.getAbsolutePath() + File.separatorChar + "Configuracion.java");
        while(iterador.hasNext()){
            obj.escribir(iterador.next());
        }
        obj.cerrar();

    }

    protected abstract void generarDTO(Tabla tbl);

    protected void generarDAO(Tabla tbl){
        Escritor objEscritor = new Escritor(path + File.separatorChar
                + "dao" + File.separatorChar + transformarNombre(tbl.getNombreTabla()) + "Dao.java");

        objEscritor.escribir("package dao;");
        objEscritor.escribir("");
        objEscritor.escribir("import dto." + transformarNombre(tbl.getNombreTabla()) + ";");
        objEscritor.escribir("import java.util.Vector;");
        objEscritor.escribir("");
        objEscritor.escribir("/**");
        objEscritor.escribir(" *");
        objEscritor.escribir(" * @author Jose Carlos Gutierrez");
        objEscritor.escribir(" */");
        objEscritor.escribir("public abstract class " + transformarNombre(tbl.getNombreTabla()) + "Dao {");
        objEscritor.escribir("");
        objEscritor.escribir("\tprotected " + transformarNombre(tbl.getNombreTabla()) + " objDto;");
        objEscritor.escribir("");
        objEscritor.escribir("\tpublic abstract void update() throws Exception;");
        objEscritor.escribir("");
        objEscritor.escribir("\tpublic abstract void delete();");
        objEscritor.escribir("");
        objEscritor.escribir("\tpublic abstract Vector<" + transformarNombre(tbl.getNombreTabla()) + "> selectTodos();");
        objEscritor.escribir("");
        objEscritor.escribir("\tpublic abstract " + transformarNombre(tbl.getNombreTabla()) + " select(int id);");
        objEscritor.escribir("");
        objEscritor.escribir("\tpublic " + transformarNombre(tbl.getNombreTabla()) + " getObjDto() {");
        objEscritor.escribir("\t\treturn objDto;");
        objEscritor.escribir("\t}");
        objEscritor.escribir("");
        objEscritor.escribir("\tpublic void setObjDto(" + transformarNombre(tbl.getNombreTabla()) + " objDto) {");
        objEscritor.escribir("\t\tthis.objDto = objDto;");
        objEscritor.escribir("\t}");
        objEscritor.escribir("");
        objEscritor.escribir("}");
        objEscritor.escribir("");
        objEscritor.cerrar();
    }

    protected void generarFactory(Vector<Tabla> tablas){
        File file = new File(path + File.separatorChar + "factory");
        if(file.exists())
            file.mkdir();
        Escritor objEscritor = new Escritor(file.getAbsolutePath() + File.separatorChar + "FactoryDao.java");
        objEscritor.escribir("package factory;");
        objEscritor.escribir("");
        objEscritor.escribir("import dal.Configuracion;");
        objEscritor.escribir("import dao.*;");
        objEscritor.escribir("");
        objEscritor.escribir("/**");
        objEscritor.escribir(" *");
        objEscritor.escribir(" * @author Jose Carlos Gutierrez");
        objEscritor.escribir(" */");
        objEscritor.escribir("public abstract class FactoryDao {");
        objEscritor.escribir("");
        objEscritor.escribir("\tprotected static FactoryDao instancia;");
        objEscritor.escribir("\tpublic static FactoryDao getFactoryInstance(){");
        objEscritor.escribir("\t\tif(instancia == null){");
        objEscritor.escribir("\t\t\tConfiguracion config = Configuracion.getConfiguracion();");
        generarFactoryConstructor(objEscritor);
        objEscritor.escribir("\t\t}");
        objEscritor.escribir("\t\treturn instancia;");
        objEscritor.escribir("\t}");
        objEscritor.escribir("");
        
        Iterator<Tabla> iterador = tablas.iterator();
        while(iterador.hasNext()){
            Tabla objTabla = iterador.next();
            objEscritor.escribir("\tpublic abstract " + 
                    transformarNombre(objTabla.getNombreTabla())+
                    "Dao getNew" +
                    transformarNombre(objTabla.getNombreTabla())+
                    "Dao();");
            objEscritor.escribir("");
        }
        
        objEscritor.escribir("}");
        objEscritor.escribir("");
        objEscritor.cerrar();
    }

    protected String transformarNombre(String nombre){
        return nombre.substring(0,1).toUpperCase()+
                    nombre.substring(1,nombre.length());
    }
    
    public abstract void generarFactoryConstructor(Escritor objEscritor);

    public void generar(Vector<Tabla> tablas){
        this.generarDAL();
        File file = new File(path + File.separatorChar + "dto");
        if(!file.exists())
            file.mkdir();
        file = new File(path + File.separatorChar + "dao");
        if(!file.exists())
            file.mkdir();
        file = new File(path + File.separatorChar + "factory");
        if(!file.exists())
            file.mkdir();
        Iterator<Tabla> iterador = tablas.iterator();
        while (iterador.hasNext()) {
            Tabla tabla = iterador.next();
            generarDTO(tabla);
            generarDAO(tabla);
        }
        generarFactory(tablas);
        generarConfiguracion();
        
    }
}
